<template>
  <div v-loading="loading" element-loading-text="加载中..." class="order_field">
    <div class="header">
      <div class="btn_group">
        <HPlainButton @click="addData"> 关联自定义字段</HPlainButton>
        <el-dropdown trigger="click">
          <HButton>
            批量操作
            <el-icon class="el-icon--right">
              <ArrowDown />
            </el-icon>
          </HButton>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="changeAll(1)">
                <el-icon>
                  <Warning />
                </el-icon>
                开启必填
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(2)">
                <el-icon>
                  <Warning />
                </el-icon>
                关闭必填
              </el-dropdown-item>
              <el-dropdown-item @click="showAll(3)">
                <el-icon>
                  <Switch />
                </el-icon>
                开启移动端显示
              </el-dropdown-item>
              <el-dropdown-item @click="showAll(33)">
                <el-icon>
                  <Switch />
                </el-icon>
                关闭移动端显示
              </el-dropdown-item>
              <el-dropdown-item @click="showAll(1)">
                <el-icon>
                  <Switch />
                </el-icon>
                开启列表查询
              </el-dropdown-item>
              <el-dropdown-item @click="showAll(11)">
                <el-icon>
                  <Switch />
                </el-icon>
                关闭列表查询
              </el-dropdown-item>
              <el-dropdown-item @click="showAll(2)">
                <el-icon>
                  <Switch />
                </el-icon>
                开启列表显示
              </el-dropdown-item>
              <el-dropdown-item @click="showAll(22)">
                <el-icon>
                  <Switch />
                </el-icon>
                关闭列表显示
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(3)">
                <el-icon>
                  <Delete />
                </el-icon>
                批量删除字段
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <!-- <el-dropdown trigger="click">
        <HButton>
          批量显示
          <el-icon class="el-icon--right">
            <ArrowDown />
          </el-icon>
        </HButton>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item @click="showAll(1)">
              <el-icon>
                <Switch />
              </el-icon>
              显示查询条件选项
            </el-dropdown-item>
            <el-dropdown-item @click="showAll(11)">
              <el-icon>
                <Switch />
              </el-icon>
              隐藏查询条件选项
            </el-dropdown-item>
            <el-dropdown-item @click="showAll(2)">
              <el-icon>
                <Switch />
              </el-icon>
              显示列表选项
            </el-dropdown-item>
            <el-dropdown-item @click="showAll(22)">
              <el-icon>
                <Switch />
              </el-icon>
              隐藏列表选项
            </el-dropdown-item>
            <el-dropdown-item @click="showAll(3)">
              <el-icon>
                <Switch />
              </el-icon>
              显示移动端选项
            </el-dropdown-item>
            <el-dropdown-item @click="showAll(33)">
              <el-icon>
                <Switch />
              </el-icon>
              隐藏移动端选项
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown> -->
      </div>
    </div>
    <div class="table">
      <el-table
        border
        stripe
        resizable
        :data="tableData"
        @selection-change="handleChange"
        height="100%"
        ref="tableDom"
      >
        <el-table-column type="selection" width="40" :align="'center'" fixed="left" />
        <el-table-column
          show-overflow-tooltip
          type="index"
          :index="indexMethod"
          label="序号"
          width="60"
          :align="'center'"
          fixed="left"
        />
        <el-table-column show-overflow-tooltip prop="name" label="字段名称" min-width="150" />
        <el-table-column prop="required" label="是否必填" width="75">
          <template #default="scope">
            <span v-if="scope.row.required">必填</span>
            <span v-if="!scope.row.required">选填</span>
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="listSelect" label="支持查询" width="110">
          <template #default="scope">
            <div class="flex-center">
              <div class="flex-center" style="display: flex; gap: 7px; align-items: center">
                <el-switch
                  v-model="scope.row.listSelect"
                  :before-change="beforeSwitchChange"
                  @change="changeShow(scope.row.listSelect, scope)"
                  :disabled="
                    !(
                      scope.row.type == 1 ||
                      scope.row.type == 3 ||
                      scope.row.type == 4 ||
                      scope.row.type == 8
                    )
                  "
                />
                <span v-if="scope.row.listSelect">显示</span>
                <span v-else>隐藏</span>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="listShow" label="列表显示" width="110">
          <template #default="scope">
            <div class="flex-center" style="display: flex; gap: 7px; align-items: center">
              <el-switch
                v-model="scope.row.listShow"
                :before-change="beforeSwitchChange"
                @change="changeShow(scope.row.listShow, scope)"
              />
              <span v-if="scope.row.listShow">显示</span>
              <span v-else>隐藏</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="mobileShow" label="移动端显示" width="110">
          <template #default="scope">
            <div class="flex-center">
              <div class="flex-center" style="display: flex; gap: 7px; align-items: center">
                <el-switch
                  v-model="scope.row.mobileShow"
                  :before-change="beforeSwitchChange"
                  @change="changeShow(scope.row.mobileShow, scope)"
                />
                <span v-if="scope.row.mobileShow">显示</span>
                <span v-else>隐藏</span>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="createTime" label="创建时间" width="150" />
        <el-table-column show-overflow-tooltip prop="updateTime" label="更新时间" width="150" />
        <el-table-column fixed="right" label="操作" width="90">
          <template #default="scope">
            <h-space>
              <h-link @click="editData(scope.row)">编辑</h-link>
              <h-link type="error" @click="handleDelOrderField(scope.row)">删除</h-link>
            </h-space>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="pagination">
      <Pagination
        ref="pagination"
        :list_total="total"
        @size-change="getList"
        @current-change="getList"
      />
    </div>

    <!-- 添加/编辑  字段弹窗 -->
    <h-dialog v-model="addDialog" :title="dialogTitle" :loading="dialogLoading">
      <el-form
        label-position="top"
        inline-message
        class="modal_form_content"
        ref="formRef"
        :rules="rules"
        :model="form"
      >
        <el-form-item label="关联字段" class="form-item" prop="workFieldId">
          <el-select
            v-model="form.workFieldId"
            class="item-type"
            placeholder="请选择字段"
            filterable
            clearable
            remote
            reserve-keyword
            remote-show-suffix
            :loading="fieldLoading"
            :remote-method="searchFieldSelect"
          >
            <el-option
              v-for="item in fieldOptions"
              :key="item.id"
              :label="item.name"
              :value="item.id"
              @click="onclickOption(item.type)"
            />
          </el-select>
        </el-form-item>
        <div class="flex-align-center" style="column-gap: 72px">
          <el-form-item label="是否必填" class="same_line">
            <div style="display: flex; align-items: center; gap: 7px">
              <el-switch v-model="form.required" />
              <span v-if="form.required">是</span>
              <span v-else>否</span>
            </div>
          </el-form-item>
          <el-form-item label="移动端显示" class="same_line">
            <div style="display: flex; align-items: center; gap: 7px">
              <el-switch v-model="form.mobileShow" />
              <span v-if="form.mobileShow">显示</span>
              <span v-else>隐藏</span>
            </div>
          </el-form-item>
        </div>
        <div class="flex-align-center" style="column-gap: 72px">
          <el-form-item label="支持查询" class="same_line">
            <div style="display: flex; align-items: center; gap: 7px">
              <el-switch v-model="form.listSelect" :disabled="listSelect" />
              <span v-if="form.listSelect" :style="{ color: listSelect ? '#999' : '#333' }"
                >开启</span
              >
              <span v-else>关闭</span>
            </div>
          </el-form-item>
          <el-form-item label="列表显示" class="same_line">
            <div style="display: flex; align-items: center; gap: 7px">
              <el-switch v-model="form.listShow" />
              <span v-if="form.listShow">显示</span>
              <span v-else>隐藏</span>
            </div>
          </el-form-item>
        </div>
      </el-form>

      <template #footer>
        <HButton is-modal type="primary" @click="saveData(formRef)">保存</HButton>
        <HButton is-modal @click="addDialog = false">取消</HButton>
      </template>
    </h-dialog>
  </div>
</template>

<script setup lang="ts">
  import Pagination from '@/components/Pagination/index.vue'
  import { ref, reactive, watch } from 'vue'
  import type { FormInstance, TableInstance } from 'element-plus'
  import {
    fieldPageSelect,
    moduleFieldSave,
    moduleFieldGetList,
    moduleFieldGetDetail,
    moduleFieldDelete,
    moduleFieldListSelect,
    moduleFieldListShow,
    moduleFieldMobileShow,
    moduleFieldRequired,
  } from '@/api/basic'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import { Delete, Warning, Switch, ArrowDown } from '@element-plus/icons-vue'
  import { useRoute } from 'vue-router'
  import { OrderField } from './types'

  const handleDelOrderField = (orderField: OrderField) => {
    if (tableDom.value) {
      tableDom.value.clearSelection()
      tableDom.value.toggleRowSelection(orderField, true)
      changeAll(3)
    }
  }

  const route = useRoute()
  const loading = ref(false)
  const tableData = ref([]) // 列表数据
  const tableDom = ref<TableInstance | null>(null) // 列表dom
  const pagination = ref() // 分页dom
  const total = ref(0) // 总数目
  const addDialog = ref(false)
  const dialogTitle = ref('')
  const dialogLoading = ref(false)
  const formRef = ref<FormInstance>() // 表单元素

  const fieldOptions = ref([])
  const fieldLoading = ref(false)
  const fieldVal = ref('')

  // 表单数据
  const form = reactive({
    id: null,
    listSelect: true,
    listShow: true,
    mobileShow: true,
    required: true,
    workFieldId: null,
  })
  const listSelect = ref(false)
  // 验证规则
  const rules = reactive({
    workFieldId: [{ required: true, message: '请选择关联字段', trigger: 'blur' }],
  })

  // 列表序号
  const indexMethod = (index: number) => {
    return index + 1
  }

  interface switchType {
    switchStatus: boolean
  }

  let switchState = reactive<switchType>({
    switchStatus: false,
  })

  // 获取自定义字段下拉
  const getOptions = (name) => {
    const data = {
      limit: 0,
      name: name,
      page: 0,
    }
    fieldPageSelect(data).then((res) => {
      fieldOptions.value = res.data.data.rows
    })
  }

  // 搜索自定义字段下拉
  const searchFieldSelect = (query) => {
    fieldVal.value = query
    if (query) {
      fieldLoading.value = true
      setTimeout(async () => {
        fieldLoading.value = false
      }, 1000)
    }
  }
  //
  const onclickOption = (val) => {
    if (val == 1 || val == 3 || val == 4 || val == 8) {
      listSelect.value = false
    } else {
      form.listSelect = false
      listSelect.value = true
    }
  }
  // 监听下拉数据变化时是否进行搜索
  watch(
    () => fieldVal.value,
    (newVal) => {
      if (newVal != '') {
        getOptions(newVal)
      } else {
        getOptions('')
      }
    },
  )

  // 关联字段
  const addData = () => {
    dialogTitle.value = '关联字段'
    addDialog.value = true
    getOptions('')
    form.id = null
    form.listSelect = true
    form.listShow = true
    form.mobileShow = true
    form.required = true
    form.workFieldId = null
  }

  // 编辑字段
  const editData = async (obj) => {
    dialogTitle.value = '编辑字段'
    addDialog.value = true
    dialogLoading.value = true
    getOptions('')
    await moduleFieldGetDetail(obj.id).then((res) => {
      form.id = res.data.data.row.id
      form.listSelect = res.data.data.row.listSelect
      form.listShow = res.data.data.row.listShow
      form.mobileShow = res.data.data.row.mobileShow
      form.required = res.data.data.row.required
      form.workFieldId = res.data.data.row.workFieldId
    })
    dialogLoading.value = false
  }

  // 获取表格选中的数据
  const selecttion = ref([])
  const handleChange = (val: any[]) => {
    if (val.length != 0) {
      val.forEach((item: { id: any }) => {
        if (Object.values(selecttion.value).indexOf(item.id) == -1) {
          selecttion.value.push(item.id)
        } else {
          selecttion.value = selecttion.value.filter((i) => i == item.id)
        }
      })
    } else {
      selecttion.value = []
    }
  }

  // 获取列表数据
  const getList = async () => {
    loading.value = true
    const data = {
      limit: pagination.value.size,
      page: pagination.value.current,
    }
    await moduleFieldGetList(data, route.params.id).then((res) => {
      tableData.value = res.data.data.rows
      total.value = parseInt(res.data.data.total)
    })
    loading.value = false
  }

  defineExpose({ getList })

  // 保存的方法
  const saveDataMethod = (method, data) => {
    dialogLoading.value = true
    method(data, route.params.id).then((res) => {
      if (res.data.success == true) {
        ElMessage({
          message: res.data.message,
          type: 'success',
          duration: 5000,
          plain: true,
          showClose: true,
        })
        addDialog.value = false
        dialogLoading.value = false
        getList()
      } else {
        ElMessage({
          message: res.data.message,
          type: 'warning',
          duration: 5000,
          plain: true,
          showClose: true,
        })
        dialogLoading.value = false
        return
      }
    })
  }

  // 保存字段
  const saveData = (formEl: FormInstance | undefined) => {
    formEl.validate((valid) => {
      if (valid) {
        saveDataMethod(moduleFieldSave, form)
      }
    })
  }

  // 批量操作的方法
  const changeMethod = (type, method, arr, status, dialog) => {
    if (arr.length == 0) {
      ElMessage({
        message: `请选择要${type}的字段`,
        type: 'warning',
        duration: 5000,
        plain: true,
        showClose: true,
      })
      return
    }
    ElMessageBox({
      type: type === '删除' ? 'error' : 'warning',
      title: '提示',
      message: `确定${type}选中的字段?`,
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    })
      .then(async () => {
        if (status != 3) {
          await method(arr, status).then((res: any) => {
            ElMessage({
              message: res.data.message,
              type: 'success',
              duration: 5000,
              plain: true,
              showClose: true,
            })
          })
        } else {
          await method(arr).then((res: any) => {
            ElMessage({
              message: res.data.message,
              type: 'success',
              duration: 5000,
              plain: true,
              showClose: true,
            })
            if (dialog != '') {
              addDialog.value = false
            }
          })
        }
        tableDom.value.clearSelection()
        await getList()
      })
      .catch(() => {
        // 不可删除catch，否则会报错
      })
  }

  // 批量更新字段 必填/选填/删除
  const changeAll = (n) => {
    switch (n) {
      case 1:
        changeMethod('更新', moduleFieldRequired, selecttion.value, true, '')
        break
      case 2:
        changeMethod('更新', moduleFieldRequired, selecttion.value, false, '')
        break
      case 3:
        changeMethod('删除', moduleFieldDelete, selecttion.value, 3, '')
        break
      case 4:
        changeMethod('删除', moduleFieldDelete, [form.id], 3, 3)
        break
    }
  }

  // 批量显示的方法
  const showMethod = (method, arr, status, obj) => {
    if (arr.length == 0) {
      ElMessage({
        message: `请选择要更新的字段`,
        type: 'warning',
        duration: 5000,
        plain: true,
        showClose: true,
      })
      return
    }
    ElMessageBox({
      type: 'warning',
      title: '提示',
      message: `确认更新选中的字段?`,
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    })
      .then(async () => {
        await method(arr, status).then((res: any) => {
          ElMessage({
            message: res.data.message,
            type: 'success',
            duration: 5000,
            plain: true,
            showClose: true,
          })
        })
        tableDom.value.clearSelection()
        await getList()
      })
      .catch(() => {
        if (obj.column && obj.column.label == '支持查询') {
          obj.row.listSelect = !obj.row.listSelect
        }
        if (obj.column && obj.column.label == '列表显示') {
          obj.row.listShow = !obj.row.listShow
        }
        if (obj.column && obj.column.label == '移动端显示') {
          obj.row.mobileShow = !obj.row.mobileShow
        }
      })
  }

  // 显示状态改变前判断
  const beforeSwitchChange = (val) => {
    switchState.switchStatus = true
    return switchState.switchStatus
  }

  // 批量更新 显示/隐藏
  const showAll = (n) => {
    switch (n) {
      case 1:
        showMethod(moduleFieldListSelect, selecttion.value, true, '')
        break
      case 11:
        showMethod(moduleFieldListSelect, selecttion.value, false, '')
        break
      case 2:
        showMethod(moduleFieldListShow, selecttion.value, true, '')
        break
      case 22:
        showMethod(moduleFieldListShow, selecttion.value, false, '')
        break
      case 3:
        showMethod(moduleFieldMobileShow, selecttion.value, true, '')
        break
      case 33:
        showMethod(moduleFieldMobileShow, selecttion.value, false, '')
        break
    }
  }

  // 显示状态改变时
  const changeShow = (val, obj) => {
    if (switchState.switchStatus) {
      if (obj.column.label == '支持查询') {
        showMethod(moduleFieldListSelect, [obj.row.id], val, obj)
      }
      if (obj.column.label == '列表显示') {
        showMethod(moduleFieldListShow, [obj.row.id], val, obj)
      }
      if (obj.column.label == '移动端显示') {
        showMethod(moduleFieldMobileShow, [obj.row.id], val, obj)
      }
    }
  }
</script>

<style scoped lang="scss">
  @import '../../index.scss';
</style>
